import {defineStore} from 'pinia';
import type {LoginWithAccountType, LoginWithPhoneType, UserBriefType} from "@/types/user";
import {loginWithAccount, loginWithPhone} from "@/services/login";
import {getUserInfo} from "@/services/user";

const STORAGE_USER_KEY = "user_result"
export const STORAGE_USER_TOKEN = "user_token"
/**
 * 共享用户登录状态
 * 方法集合
 *  - 登录信息是否有效
 *  - 执行登录
 *  - 获取登录信息
 *  - 清除登录信息
 */
export const useUserStore = defineStore('user', {
    // 也可以这样定义
    state: () => ({
        user: {} as UserBriefType,
        token: ""
    }),
    actions: {
        _storeUserLoginResult(rs: UserBriefType) {
            this.user = rs
            uni.setStorageSync(STORAGE_USER_KEY, JSON.stringify(this.user))
        },
        // 执行登录
        loginWithPhone(form: LoginWithPhoneType): Promise<Boolean> {
            return loginWithPhone(form).then((r) => {
                this.token = r.data;
                uni.setStorageSync(STORAGE_USER_TOKEN, this.token);
                return Promise.resolve(true)
            }).catch((e) => {
                console.log("@loginWithPhone#error", e);
                uni.showToast({
                    title: e.msg,
                    icon: "none"
                });
                return Promise.reject(false);
            });
        },
        loginWithAccount(form: LoginWithAccountType): Promise<Boolean> {
            return loginWithAccount(form).then((r) => {
                // 保存登录成功的用户信息
                this.token = r.data
                uni.setStorageSync(STORAGE_USER_TOKEN, this.token)
                return Promise.resolve(true)
            }).catch((e) => {
                console.log("@loginWithPhone#error", JSON.stringify(e));
                uni.showToast({
                    title: e.msg,
                    icon: "none"
                });
                return Promise.reject(false);
            })
        },
        // 清除登录信息
        logout() {
            uni.removeStorageSync(STORAGE_USER_KEY)
            uni.removeStorageSync(STORAGE_USER_TOKEN)
            this.user = {} as UserBriefType
            this.token = ""
            return true
        },
        // 判断是否登录
        isLogin(): boolean {
            // 判断storage中是否存在
            try {
                const storageToken = uni.getStorageSync(STORAGE_USER_TOKEN)
                if (storageToken) {
                    console.log("@get data from storage ", storageToken)
                    return true
                }
                return false
            } catch (e) {
                console.log("@get data from storage failed ", e)
                return false
            }
        },
        /**
         * 请求用户信息
         */
        reqUserInfo(): UserBriefType | void {
            getUserInfo().then((r) => {
                this._storeUserLoginResult(r.data)
                return r.data
            }).catch((e) => {
                uni.showToast({
                    title: "获取用户信息失败 " + e,
                    icon: "none"
                })
                console.log("@reqUserInfo#error ", e)
            })

        },
        /**
         * 获取用户登录信息
         * @return UserBriefType | void
         */
        getUser(): UserBriefType | void {
            if (Object.getOwnPropertyNames(this.user).length != 0) {
                return this.user
            }
            // 当pinia中不存在时通过storage获取
            if (!this.isLogin()) {
                // 返回值是undefined
                return
            }
            const storageUserStr = uni.getStorageSync(STORAGE_USER_KEY)
            // token有效但是缓存数据不存在，则重新请求接口
            if (storageUserStr) {
                console.log("@try get not exists key from storage ", storageUserStr, typeof storageUserStr)
                this.user = JSON.parse(storageUserStr)
                return this.user
            }
            return this.reqUserInfo()
        },
        getToken() {
            if (this.token) {
                return this.token
            }
            if (this.isLogin()) {
                this.token = uni.getStorageSync(STORAGE_USER_TOKEN)
                return this.token
            }
            return
        }
    },
});
